﻿using Furion.Reflection;
using Newtonsoft.Json;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DemoUser.Application.User.Filter
{
    public class LogDispatchProxy : AspectDispatchProxy, IDispatchProxy
    {
        /// <summary>
        /// 当前服务实例
        /// </summary>
        public object Target { get; set; }

        /// <summary>
        /// 服务提供器，可以用来解析服务，如：Services.GetService()
        /// </summary>
        public IServiceProvider Services { get; set; }

        /// <summary>
        /// 拦截方法
        /// </summary>
        /// <param name="method"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public override object Invoke(MethodInfo method, object[] args)
        {
            //Console.WriteLine("SayHello 方法被调用了");

            var result = method.Invoke(Target, args);
            Type type = result.GetType();
            //Console.WriteLine(type.Name);

            string rtj = result.ToJson();
            //Console.WriteLine(type.ToJson());

            //Console.WriteLine(rtj);
            //ObjectResult or = JsonConvert.DeserializeObject<ObjectResult>(rtj);
            //Console.WriteLine(or);
            //Object ov = or.Value;
            //string ovstr = ov.ToJson();
            //Console.WriteLine(ovstr);

            
            if (type != null)
            {
                List<Object> tl = null;
                Object to = null;
                //Console.WriteLine(type.FullName);
                //Console.WriteLine(type.Name);
                //Console.WriteLine(tgtd.Name);
                if (type.IsGenericType)
                {
                    //Type tgtd = type.GetGenericTypeDefinition();
                    Type tga = type.GetGenericArguments()[0];
                    tl = JsonConvert.DeserializeObject<List<Object>>(rtj);
                    for(int i = 0;i < tl.Count;i++)
                    {
                        //Console.WriteLine(tl[i].ToString());
                        tl[i] = UpdateData(tga, tl[i]);
                    }
                    result = tl;
                }else
                {
                    to = JsonConvert.DeserializeObject(rtj);
                    if(to != null)
                    {
                        //Console.WriteLine(to);
                        to = UpdateData(type, to);
                    }
                    result = to;
                }
            }

            //Console.WriteLine("SayHello 方法返回值：" + result.ToJson());
            return result;
        }

        //修改数据
        private object UpdateData(Type type, object to)
        {
            Random random = new Random();
            //Console.WriteLine(to);
            //Console.WriteLine(type.ToJson());
            PropertyInfo[] properties = type.GetProperties();

            for(int i = 0;i < properties.Length;i++ )
            {
                if(properties[i].Name != "Id")
                {
                    if (properties[i].PropertyType == typeof(int))
                    {
                        Object value = properties[i].GetValue(to);
                        Console.WriteLine(value.ToString());
                        //Console.WriteLine(properties[i].GetValue(to, null));
                        //Type tto = to.GetType();
                        //PropertyInfo pi = tto.GetProperty(properties[i].Name);
                        //int xxo = (int)pi.GetValue(to);
                        //Console.WriteLine(xxo);
                        //xxo += random.Next(-5, 5);
                        //pi.SetValue(to, xxo);
                        //修改数据
                        //Console.WriteLine(prop.Name);
                        //Console.WriteLine(prop.PropertyType);
                    }else
                    {

                    }
                }
                
            }

            return to;
        }

        // 异步无返回值
        public async override Task InvokeAsync(MethodInfo method, object[] args)
        {
            //Console.WriteLine("SayHello 方法被调用了");

            var task = method.Invoke(Target, args) as Task;
            await task;

            //Console.WriteLine("SayHello 方法调用完成");
        }

        // 异步带返回值
        public async override Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args)
        {
            //Console.WriteLine("SayHello 方法被调用了");

            var taskT = method.Invoke(Target, args) as Task<T>;
            var result = await taskT;
            var t = result.GetType();

            //Console.WriteLine("SayHello 方法返回值：" + result);

            return result;
        }
    }
}
